use std::cmp::Ordering;
use std::collections::BinaryHeap;

#[derive(Debug, Clone)]
pub struct Path {
    pub value: Vec<String>,
    pub score: f64,
}

impl Path {
    pub fn new(value: Vec<String>, score: f64) -> Self {
        Path { value, score }
    }
}

impl Eq for Path {}

impl PartialEq for Path {
    fn eq(&self, other: &Self) -> bool {
        self.score == other.score
    }
}

// 实现 PartialOrd 以支持比较操作
impl PartialOrd for Path {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        // 我们希望最大堆，因此比较顺序相反
        other.score.partial_cmp(&self.score)
    }
}

impl Ord for Path {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).unwrap_or(Ordering::Equal)
    }
}

pub struct PrioritySet {
    pub paths: BinaryHeap<Path>,
    pub capacity: usize,
}

impl PrioritySet {
    pub fn new(max_size: usize) -> Self {
        Self {
            paths: BinaryHeap::new(),
            capacity: max_size,
        }
    }

    pub fn put(&mut self, item: Path) {
        if self.paths.len() < self.capacity {
            self.paths.push(item);
        } else {
            // 如果当前项比堆中最小项大，则替换
            if let Some(smallest) = self.paths.peek() {
                if item.score > smallest.score {
                    self.paths.pop();
                    self.paths.push(item);
                }
            }
        }
    }
}